package org.jdarwinbots.logic;

import java.util.Stack;

import junit.framework.TestCase;

public class LogicTests extends TestCase {
	
	//Basic layout for test cases:
	//STEP 1: Check operativity with certain examples
	//STEP 2: Check for correct stack manipulation
	//STEP 3: For memory manipulation, check booleans affect operation

	
	public void testAbs(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator abs = DefaultOperators.getOperator("abs");
		
		
		//STEP 1: Test functionality
		intstack.push(30);
		abs.execute(memory, intstack, boolstack);
		assertEquals(30, (int)intstack.pop());
		
		intstack.push(-10);
		abs.execute(memory, intstack, boolstack);
		assertEquals(10, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(false);
		intstack.push(-30);
		abs.execute(memory, intstack, boolstack);
		assertEquals(30, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	
	public void testAdd(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator add = DefaultOperators.getOperator("add");
		
		
		//STEP 1: Test functionality
		intstack.push(12);
		intstack.push(30);
		add.execute(memory, intstack, boolstack);
		assertEquals(42, (int)intstack.pop());
		
		intstack.push(40);
		intstack.push(-10);
		add.execute(memory, intstack, boolstack);
		assertEquals(30, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(false);
		intstack.push(12);
		intstack.push(30);
		add.execute(memory, intstack, boolstack);
		assertEquals(42, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}

	
	public void testAnd(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator and = DefaultOperators.getOperator("and");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(true);
		and.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());

		boolstack.push(false);
		boolstack.push(false);
		and.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		boolstack.push(false);
		boolstack.push(true);
		and.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(true);
		boolstack.push(false);
		boolstack.push(true);
		and.execute(memory, intstack, boolstack);
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testAngle(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator angle = DefaultOperators.getOperator("angle");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(0);
		angle.execute(memory, intstack, boolstack);
		assertEquals(157, (int)intstack.pop());

		intstack.push(42);
		intstack.push(0);
		angle.execute(memory, intstack, boolstack);
		assertEquals(157, (int)intstack.pop());
		
		intstack.push(0);
		intstack.push(1);
		angle.execute(memory, intstack, boolstack);
		assertEquals(314, (int)intstack.pop());
		
		//STEP 2: Stack Manipulation

		intstack.push(2);
		boolstack.push(false);
		intstack.push(0);
		intstack.push(1);
		angle.execute(memory, intstack, boolstack);
		assertEquals(314, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testApproxEqual(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator ae = DefaultOperators.getOperator("%=");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(10);
		ae.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());

		intstack.push(10);
		intstack.push(11);
		ae.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		
		intstack.push(11);
		intstack.push(6);
		ae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		
		intstack.push(11);
		intstack.push(16);
		ae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(22);
		intstack.push(10);
		intstack.push(10);
		ae.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		assertEquals(22, (int)intstack.pop());
		
	}
	
	public void testApproxNotEqual(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator ae = DefaultOperators.getOperator("!%=");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(10);
		ae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		intstack.push(10);
		intstack.push(11);
		ae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		
		intstack.push(11);
		intstack.push(6);
		ae.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		
		intstack.push(11);
		intstack.push(16);
		ae.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(22);
		intstack.push(10);
		intstack.push(10);
		ae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		assertEquals(22, (int)intstack.pop());
		
	}
	
	public void testBWAnd(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator and = DefaultOperators.getOperator("&");
		
		
		//STEP 1: Test functionality
		intstack.push(19);
		intstack.push(26);
		and.execute(memory, intstack, boolstack);
		assertEquals(18, (int)intstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(19);
		intstack.push(26);
		and.execute(memory, intstack, boolstack);
		assertEquals(18, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testBWCompl(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator compl = DefaultOperators.getOperator("~");
		
		
		//STEP 1: Test functionality
		intstack.push(3);
		compl.execute(memory, intstack, boolstack);
		assertEquals(-4, (int)intstack.pop());
		

		intstack.push(-3);
		compl.execute(memory, intstack, boolstack);
		assertEquals(2, (int)intstack.pop());
		
		//STEP 2: Stack manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(-3);
		compl.execute(memory, intstack, boolstack);
		assertEquals(2, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testBWLeft(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator left = DefaultOperators.getOperator("<<");
		
		
		//STEP 1: Test functionality
		intstack.push(19);
		intstack.push(1);
		left.execute(memory, intstack, boolstack);
		assertEquals(38, (int)intstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(19);
		intstack.push(1);
		left.execute(memory, intstack, boolstack);
		assertEquals(38, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testBWRight(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator right = DefaultOperators.getOperator(">>");
		
		
		//STEP 1: Test functionality
		intstack.push(19);
		intstack.push(1);
		right.execute(memory, intstack, boolstack);
		assertEquals(9, (int)intstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(19);
		intstack.push(1);
		right.execute(memory, intstack, boolstack);
		assertEquals(9, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testBWXor(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator xor = DefaultOperators.getOperator("^");
		
		
		//STEP 1: Test functionality
		intstack.push(25);
		intstack.push(11);
		xor.execute(memory, intstack, boolstack);
		assertEquals(18, (int)intstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(25);
		intstack.push(11);
		xor.execute(memory, intstack, boolstack);
		assertEquals(18, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testCeil(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator ceil = DefaultOperators.getOperator("ceil");
		
		
		//STEP 1: Test functionality
		intstack.push(25);
		intstack.push(11);
		ceil.execute(memory, intstack, boolstack);
		assertEquals(25, (int)intstack.pop());

		intstack.push(-25);
		intstack.push(-11);
		ceil.execute(memory, intstack, boolstack);
		assertEquals(-11, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(25);
		intstack.push(11);
		ceil.execute(memory, intstack, boolstack);
		assertEquals(25, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testClear(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator clear = DefaultOperators.getOperator("clear");
		
		
		//STEP 1: Test functionality
		intstack.push(1);
		intstack.push(2);
		intstack.push(3);
		clear.execute(memory, intstack, boolstack);
		assertEquals(true, intstack.isEmpty());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(1);
		intstack.push(2);
		intstack.push(3);
		clear.execute(memory, intstack, boolstack);
		assertEquals(true, intstack.isEmpty());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testClearbool(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator clear = DefaultOperators.getOperator("clearbool");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(false);
		boolstack.push(true);
		clear.execute(memory, intstack, boolstack);
		assertEquals(true, boolstack.isEmpty());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(true);
		boolstack.push(false);
		boolstack.push(true);
		clear.execute(memory, intstack, boolstack);
		assertEquals(true, boolstack.isEmpty());
		assertEquals(42, (int)intstack.pop());
	}
	
	//Should be the same as clearbool...for now.
	public void testCond(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator clear = DefaultOperators.getOperator("cond");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(false);
		boolstack.push(true);
		clear.execute(memory, intstack, boolstack);
		assertEquals(true, boolstack.isEmpty());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(true);
		boolstack.push(false);
		boolstack.push(true);
		clear.execute(memory, intstack, boolstack);
		assertEquals(true, boolstack.isEmpty());
		assertEquals(42, (int)intstack.pop());
	}
	
	public void testCustApproxEqual(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator cae = DefaultOperators.getOperator("~=");
		
		
		//STEP 1: Test functionality
		intstack.push(100);
		intstack.push(150);
		intstack.push(50);
		cae.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());

		intstack.push(900);
		intstack.push(150);
		intstack.push(50);
		cae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		intstack.push(-100);
		intstack.push(150);
		intstack.push(50);
		cae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(true);
		intstack.push(900);
		intstack.push(150);
		intstack.push(50);
		cae.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testCustApproxNotEqual(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator cane = DefaultOperators.getOperator("!~=");
		
		
		//STEP 1: Test functionality
		intstack.push(100);
		intstack.push(150);
		intstack.push(50);
		cane.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		intstack.push(900);
		intstack.push(150);
		intstack.push(50);
		cane.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());

		intstack.push(-100);
		intstack.push(150);
		intstack.push(50);
		cane.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(true);
		intstack.push(900);
		intstack.push(150);
		intstack.push(50);
		cane.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testDec(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator dec = DefaultOperators.getOperator("dec");
		
		
		//STEP 1: Test functionality
		intstack.push(5);
		dec.execute(memory, intstack, boolstack);
		assertEquals(-1, memory[5]);
		
		
		//STEP 2: Stack Manipulation
		intstack.push(7);
		boolstack.push(true);
		intstack.push(5);
		dec.execute(memory, intstack, boolstack);
		assertEquals(-2, memory[5]);
		assertEquals(7, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
		
		//STEP 3: Conditional Functionality
		intstack.push(5);
		boolstack.push(false);
		dec.execute(memory, intstack, boolstack);
		assertEquals(-2, memory[5]);
	}
	
	public void testDecval(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator dec = DefaultOperators.getOperator("--");
		
		
		//STEP 1: Test functionality
		intstack.push(5);
		dec.execute(memory, intstack, boolstack);
		assertEquals(4, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(7);
		boolstack.push(true);
		intstack.push(5);
		dec.execute(memory, intstack, boolstack);
		assertEquals(4, (int)intstack.pop());
		assertEquals(7, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testDiv(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator div = DefaultOperators.getOperator("div");
		
		
		//STEP 1: Test functionality
		intstack.push(5);
		intstack.push(2);
		div.execute(memory, intstack, boolstack);
		assertEquals(2, (int)intstack.pop());
		
		intstack.push(42);
		intstack.push(2);
		div.execute(memory, intstack, boolstack);
		assertEquals(21, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(7);
		boolstack.push(true);
		intstack.push(42);
		intstack.push(2);
		div.execute(memory, intstack, boolstack);
		assertEquals(21, (int)intstack.pop());		
		assertEquals(7, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testDrop(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator drop = DefaultOperators.getOperator("drop");
		
		
		//STEP 1: Test functionality
		intstack.push(42);
		drop.execute(memory, intstack, boolstack);
		assertTrue(intstack.isEmpty());
		
		
		//STEP 2: Stack Manipulation
		boolstack.push(true);
		intstack.push(24);
		intstack.push(42);
		drop.execute(memory, intstack, boolstack);
		assertEquals(24, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testDropBool(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator drop = DefaultOperators.getOperator("dropbool");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		drop.execute(memory, intstack, boolstack);
		assertTrue(boolstack.isEmpty());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		boolstack.push(true);
		drop.execute(memory, intstack, boolstack);
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testDup(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator dup = DefaultOperators.getOperator("dup");
		
		
		//STEP 1: Test functionality
		intstack.push(42);
		dup.execute(memory, intstack, boolstack);
		assertEquals(42, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		intstack.push(24);
		boolstack.push(true);
		dup.execute(memory, intstack, boolstack);
		assertEquals(24, (int)intstack.pop());
		assertEquals(24, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());

	}
	
	public void testDupBool(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator dup = DefaultOperators.getOperator("dupbool");
		
		
		//STEP 1: Test functionality
		boolstack.push(false);
		dup.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(true);
		boolstack.push(false);
		dup.execute(memory, intstack, boolstack);
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testEquality(){
		//Test Setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator equal = DefaultOperators.getOperator("=");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(10);
		equal.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		
		intstack.push(-10);
		intstack.push(10);
		equal.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(10);
		intstack.push(10);
		equal.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertFalse(boolstack.pop());
	}
	
	public void testFloor(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator floor = DefaultOperators.getOperator("floor");
		
		
		//STEP 1: Test functionality
		intstack.push(25);
		intstack.push(11);
		floor.execute(memory, intstack, boolstack);
		assertEquals(11, (int)intstack.pop());

		intstack.push(-25);
		intstack.push(-11);
		floor.execute(memory, intstack, boolstack);
		assertEquals(-25, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(25);
		intstack.push(11);
		floor.execute(memory, intstack, boolstack);
		assertEquals(11, (int)intstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testGreater(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator greater = DefaultOperators.getOperator(">");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(20);
		greater.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());

		intstack.push(20);
		intstack.push(20);
		greater.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		intstack.push(30);
		intstack.push(20);
		greater.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		
		
		//STEP 2: Stack manipulation
		boolstack.push(false);
		intstack.push(10);
		intstack.push(30);
		intstack.push(20);
		greater.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertEquals(10, (int)intstack.pop());
		assertFalse(boolstack.pop());
	}
	
	public void testGreaterOrEqual(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator goe = DefaultOperators.getOperator(">=");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(20);
		goe.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());

		intstack.push(20);
		intstack.push(20);
		goe.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		
		intstack.push(30);
		intstack.push(20);
		goe.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		
		
		//STEP 2: Stack manipulation
		boolstack.push(false);
		intstack.push(10);
		intstack.push(30);
		intstack.push(20);
		goe.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertEquals(10, (int)intstack.pop());
		assertFalse(boolstack.pop());
	}
	
	public void testInc(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator inc = DefaultOperators.getOperator("inc");
		
		
		//STEP 1: Test functionality
		intstack.push(5);
		inc.execute(memory, intstack, boolstack);
		assertEquals(1, memory[5]);
		
		
		//STEP 2: Stack Manipulation
		intstack.push(7);
		boolstack.push(true);
		intstack.push(5);
		inc.execute(memory, intstack, boolstack);
		assertEquals(2, memory[5]);
		assertEquals(7, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
		
		//STEP 3: Conditional Functionality
		intstack.push(5);
		boolstack.push(false);
		inc.execute(memory, intstack, boolstack);
		assertEquals(2, memory[5]);
	}
	
	public void testIncval(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator inc = DefaultOperators.getOperator("++");
		
		
		//STEP 1: Test functionality
		intstack.push(5);
		inc.execute(memory, intstack, boolstack);
		assertEquals(6, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(7);
		boolstack.push(true);
		intstack.push(5);
		inc.execute(memory, intstack, boolstack);
		assertEquals(6, (int)intstack.pop());
		assertEquals(7, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testLess(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator less = DefaultOperators.getOperator("<");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(20);
		less.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());

		intstack.push(20);
		intstack.push(20);
		less.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		intstack.push(30);
		intstack.push(20);
		less.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		
		//STEP 2: Stack manipulation
		boolstack.push(false);
		intstack.push(10);
		intstack.push(30);
		intstack.push(20);
		less.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		assertEquals(10, (int)intstack.pop());
		assertFalse(boolstack.pop());
	}
	
	public void testLessOrEqual(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator loe = DefaultOperators.getOperator("<=");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(20);
		loe.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());

		intstack.push(20);
		intstack.push(20);
		loe.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		
		intstack.push(30);
		intstack.push(20);
		loe.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		
		//STEP 2: Stack manipulation
		boolstack.push(false);
		intstack.push(10);
		intstack.push(30);
		intstack.push(20);
		loe.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		assertEquals(10, (int)intstack.pop());
		assertFalse(boolstack.pop());
	}
	
	public void testMod(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator mod = DefaultOperators.getOperator("mod");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(2);
		mod.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 0);
		
		intstack.push(20);
		intstack.push(0);
		mod.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 0);
		
		//STEP 2: Stack Manipulation
		boolstack.push(true);
		intstack.push(42);
		intstack.push(10);
		intstack.push(2);
		mod.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 0);
		assertEquals((int)intstack.pop(), 42);
		assertEquals((boolean)boolstack.pop(), true);
	}
	
	public void testMult(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator mult = DefaultOperators.getOperator("mult");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(2);
		mult.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 20);
		
		intstack.push(-7);
		intstack.push(6);
		mult.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), -42);
		
		//STEP 2: Stack Manipulation
		boolstack.push(true);
		intstack.push(42);
		intstack.push(-7);
		intstack.push(6);
		mult.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), -42);
		assertEquals((int)intstack.pop(), 42);
		assertEquals((boolean)boolstack.pop(), true);
	}
	
	public void testNeg(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator neg = DefaultOperators.getOperator("-");
		
		
		//STEP 1: Test functionality
		intstack.push(20);
		neg.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), -20);
		
		intstack.push(-7);
		neg.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 7);
		
		//STEP 2: Stack Manipulation
		boolstack.push(true);
		intstack.push(42);
		intstack.push(12);
		neg.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), -12);
		assertEquals((int)intstack.pop(), 42);
		assertEquals((boolean)boolstack.pop(), true);
	}
	
	public void testNot(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator not = DefaultOperators.getOperator("not");
		
		
		//STEP 1: Test functionality
		boolstack.push(false);
		not.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());

		boolstack.push(true);
		not.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		
		//STEP 2: Stack manipulation
		boolstack.push(true);
		intstack.push(42);
		boolstack.push(false);
		not.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertTrue(boolstack.pop());
		assertEquals(42, (int)intstack.pop());
	}
	
	public void testInequality(){
		//Test Setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator ne = DefaultOperators.getOperator("!=");
		
		
		//STEP 1: Test functionality
		intstack.push(10);
		intstack.push(10);
		ne.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		intstack.push(-10);
		intstack.push(10);
		ne.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(42);
		boolstack.push(false);
		intstack.push(10);
		intstack.push(10);
		ne.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		assertEquals(42, (int)intstack.pop());
		assertFalse(boolstack.pop());
	}
	
	public void testOr(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator or = DefaultOperators.getOperator("or");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(true);
		or.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());

		boolstack.push(false);
		boolstack.push(false);
		or.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		boolstack.push(false);
		boolstack.push(true);
		or.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(true);
		boolstack.push(false);
		boolstack.push(true);
		or.execute(memory, intstack, boolstack);
		assertEquals(2, (int)intstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
		assertEquals(true, (boolean)boolstack.pop());
	}
	
	public void testOver(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator over = DefaultOperators.getOperator("over");
		
		
		//STEP 1: Test functionality
		intstack.push(1);
		intstack.push(2);
		over.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 1);
		assertEquals((int)intstack.pop(), 2);
		assertEquals((int)intstack.pop(), 1);
		
		//STEP 2: Stack manipulation
		intstack.push(42);
		boolstack.push(true);
		intstack.push(1);
		intstack.push(2);
		over.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 1);
		assertEquals((int)intstack.pop(), 2);
		assertEquals((int)intstack.pop(), 1);
		assertEquals((int)intstack.pop(), 42);
		assertTrue(boolstack.pop());
	}
	
	public void testOverbool(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator over = DefaultOperators.getOperator("overbool");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(false);
		over.execute(memory, intstack, boolstack);
		assertEquals((boolean)boolstack.pop(), true);
		assertEquals((boolean)boolstack.pop(), false);
		assertEquals((boolean)boolstack.pop(), true);
		
		//STEP 2: Stack manipulation
		intstack.push(42);
		boolstack.push(true);
		boolstack.push(true);
		boolstack.push(false);
		over.execute(memory, intstack, boolstack);
		assertEquals((boolean)boolstack.pop(), true);
		assertEquals((boolean)boolstack.pop(), false);
		assertEquals((boolean)boolstack.pop(), true);
		assertEquals((int)intstack.pop(), 42);
		assertTrue(boolstack.pop());
	}
	
	public void testPow(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator pow = DefaultOperators.getOperator("pow");
		
		
		//STEP 1: Test functionality
		intstack.push(3);
		intstack.push(2);
		pow.execute(memory, intstack, boolstack);
		assertEquals(9, (int)intstack.pop());
		
		
		//STEP 2: Stack manipulation

		intstack.push(42);
		boolstack.push(true);
		intstack.push(3);
		intstack.push(2);
		pow.execute(memory, intstack, boolstack);
		assertEquals(9, (int)intstack.pop());
		assertEquals((int)intstack.pop(), 42);
		assertTrue(boolstack.pop());
	}
	
	public void testPyth(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator pyth = DefaultOperators.getOperator("pyth");
		
		
		//STEP 1: Test functionality
		intstack.push(3);
		intstack.push(4);
		pyth.execute(memory, intstack, boolstack);
		assertEquals(5, (int)intstack.pop());
		
		
		//STEP 2: Stack manipulation

		intstack.push(42);
		boolstack.push(true);
		intstack.push(3);
		intstack.push(4);
		pyth.execute(memory, intstack, boolstack);
		assertEquals(5, (int)intstack.pop());
		assertEquals((int)intstack.pop(), 42);
		assertTrue(boolstack.pop());
	}
	
	//TODO rnd testing
	
	public void testSign(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator sgn = DefaultOperators.getOperator("sgn");
		
		
		//STEP 1: Test functionality
		intstack.push(42);
		sgn.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 1);
		
		intstack.push(-7);
		sgn.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), -1);
		
		sgn.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), 0);
		
		//STEP 2: Stack Manipulation
		boolstack.push(true);
		intstack.push(42);
		intstack.push(-7);
		sgn.execute(memory, intstack, boolstack);
		assertEquals((int)intstack.pop(), -1);
		assertEquals((int)intstack.pop(), 42);
		assertEquals((boolean)boolstack.pop(), true);
	}
	
	public void testRoot(){

		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator sqr = DefaultOperators.getOperator("sqr");
		
		
		//STEP 1: Test functionality
		intstack.push(9);
		sqr.execute(memory, intstack, boolstack);
		assertEquals(3, (int)intstack.pop());

		intstack.push(-9);
		sqr.execute(memory, intstack, boolstack);
		assertEquals(3, (int)intstack.pop());
		
		//STEP 2: Stack manipulation

		intstack.push(42);
		boolstack.push(true);
		intstack.push(-9);
		sqr.execute(memory, intstack, boolstack);
		assertEquals(3, (int)intstack.pop());
		assertEquals((int)intstack.pop(), 42);
		assertTrue(boolstack.pop());
	}
	
	public void testStart(){

		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator start = DefaultOperators.getOperator("start");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(true);
		boolstack.push(true);
		start.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());

		boolstack.push(false);
		boolstack.push(true);
		boolstack.push(true);
		start.execute(memory, intstack, boolstack);
		assertFalse(boolstack.pop());
		
		
		//STEP 2: Stack manipulation
		intstack.push(10);
		boolstack.push(true);
		boolstack.push(true);
		boolstack.push(true);
		start.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertEquals(10, (int)intstack.pop());
	}
	
	public void testStop(){

		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator stop = DefaultOperators.getOperator("stop");
		
		
		//STEP 1/2: Test functionality//Stack Manipulation
		boolstack.push(true);
		boolstack.push(true);
		boolstack.push(true);
		intstack.push(11);
		intstack.push(22);
		intstack.push(33);
		stop.execute(memory, intstack, boolstack);
		assertTrue(boolstack.isEmpty());
		assertTrue(intstack.isEmpty());
	}
	
	public void testStore(){


		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator store = DefaultOperators.getOperator("store");
		
		
		//STEP 1: Test functionality
		intstack.push(42);
		intstack.push(2);
		store.execute(memory, intstack, boolstack);
		assertEquals(42, memory[2]);
		
		//STEP 2: Stack manipulation
		boolstack.push(true);
		intstack.push(12);
		intstack.push(42);
		intstack.push(3);
		store.execute(memory, intstack, boolstack);
		assertEquals(42, memory[3]);
		assertTrue(boolstack.pop());
		assertEquals(12, (int)intstack.pop());
		
		//STEP 3: Conditional Functionality
		boolstack.push(false);
		intstack.push(12);
		intstack.push(4);
		store.execute(memory, intstack, boolstack);
		assertEquals(0, memory[4]);
	}
	
	public void testSub(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator sub = DefaultOperators.getOperator("sub");
		
		
		//STEP 1: Test functionality
		intstack.push(30);
		intstack.push(2);
		sub.execute(memory, intstack, boolstack);
		assertEquals(28, (int)intstack.pop());
		
		intstack.push(40);
		intstack.push(-10);
		sub.execute(memory, intstack, boolstack);
		assertEquals(50, (int)intstack.pop());
		
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(false);
		intstack.push(40);
		intstack.push(-10);
		sub.execute(memory, intstack, boolstack);
		assertEquals(50, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testSwap(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator swap = DefaultOperators.getOperator("swap");
		
		
		//STEP 1: Test functionality
		intstack.push(30);
		intstack.push(2);
		swap.execute(memory, intstack, boolstack);
		assertEquals(30, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(false);
		intstack.push(30);
		intstack.push(2);
		swap.execute(memory, intstack, boolstack);
		assertEquals(30, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testSwapbool(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator swap = DefaultOperators.getOperator("swapbool");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(false);
		swap.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertFalse(boolstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(false);
		boolstack.push(true);
		boolstack.push(false);
		swap.execute(memory, intstack, boolstack);
		assertTrue(boolstack.pop());
		assertFalse(boolstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
	
	public void testXor(){
		//Test setup
		Stack<Integer> intstack = new Stack<Integer>();
		Stack<Boolean> boolstack = new Stack<Boolean>();
		int[] memory = new int[10];
		Operator xor = DefaultOperators.getOperator("xor");
		
		
		//STEP 1: Test functionality
		boolstack.push(true);
		boolstack.push(true);
		xor.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		boolstack.push(false);
		boolstack.push(false);
		xor.execute(memory, intstack, boolstack);
		assertEquals(false, (boolean)boolstack.pop());

		boolstack.push(false);
		boolstack.push(true);
		xor.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		
		//STEP 2: Stack Manipulation
		intstack.push(2);
		boolstack.push(false);
		boolstack.push(false);
		boolstack.push(true);
		xor.execute(memory, intstack, boolstack);
		assertEquals(true, (boolean)boolstack.pop());
		assertEquals(2, (int)intstack.pop());
		assertEquals(false, (boolean)boolstack.pop());
	}
}
